package com.happysunrise.nru.services.imp;

import com.happysunrise.nru.enumerations.ApplyStatusEnum;
import com.happysunrise.nru.enumerations.NoticeTypeEnum;
import com.happysunrise.nru.enumerations.ResultTypeEnum;
import com.happysunrise.nru.enumerations.TeamRoleEnum;
import com.happysunrise.nru.managers.INoticeManager;
import com.happysunrise.nru.managers.ITeamManager;
import com.happysunrise.nru.managers.IUserManager;
import com.happysunrise.nru.models.*;
import com.happysunrise.nru.models.Apply;
import com.happysunrise.nru.models.Result;
import com.happysunrise.nru.models.Team;
import com.happysunrise.nru.models.UserTeam;
import com.happysunrise.nru.services.ITeamService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;

/**
 * TeamService.
 * <p>
 * Created by liukaixin on 16/7/16.
 */
@Service
public class TeamService implements ITeamService {

    private static final Logger LOGGER = LoggerFactory
            .getLogger(TeamService.class);

    @Autowired
    private ITeamManager teamManager;
    @Autowired
    private IUserManager userManager;
    @Autowired
    private INoticeManager noticeManager;

    /**
     * 获得发布状态的团队列表.
     *
     * @param page 页码
     * @param rows 条数
     * @return 结果集
     */
    @Override
    public Result<List<Team>> getReleasedTeams(Integer page, Integer rows) {
        Result<List<Team>> result = new Result<>();
        result.setBean(teamManager.getReleasedTeams(page, rows));
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("获取团队列表" + ResultTypeEnum.SUCCESS.getDescription());
        return result;
    }

    /**
     * 添加加入团队申请.
     *
     * @param apply 申请
     * @return 结果集
     */
    @Override
    public Result<String> addJoinTeamApply(Apply apply) {
        Result<String> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("添加团队申请成功");
        try {
            teamManager.addJoinTeamApply(apply);
        } catch (DuplicateKeyException e) {
            LOGGER.debug("重复插入 加入团队申请:", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("您已提交过加入申请,请耐心等待~");
            return result;
        } catch (RuntimeException e) {
            LOGGER.error("添加加入团队申请异常:", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("添加加入团队申请失败");
            return result;
        }
        // todo move to push service
        Notice notice = new Notice();
        notice.setUserId(apply.getTeamCreatorId());
        notice.setCategory(NoticeTypeEnum.TEAM_NOTICE.getTypeCode());
        notice.setIdForCategory(apply.getId());
        notice.setTitle("您收到一条团队申请");
        notice.setInfo("团队名称:" + apply.getTeamName() +
                "; " + "比赛名称:" + apply.getCompetitionName());
        try {
            noticeManager.addNotice(notice);
        } catch (DuplicateKeyException e) {
            LOGGER.debug("重复插入 通知:", e);
        } catch (RuntimeException e) {
            noticeManager.addNotice(notice);
        }
        return result;
    }

    @Override
    public Result<String> createTeam(Team team) {
        Result<String> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("创建团队成功");
        try {
            teamManager.createTeam(team);
        } catch (DuplicateKeyException e) {
            LOGGER.debug("重复插入Team表,已忽略", e);
        } catch (RuntimeException e) {
            LOGGER.error("创建团队异常:", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("创建团队失败");
            return result;
        }
        try {
            Integer teamId = teamManager.getTeamIdByUserIdAndCompId(
                    team.getUserId(), team.getCompetitionId());
            UserTeam userTeam = new UserTeam();
            userTeam.setCompetitionName(team.getCompetitionName());
            userTeam.setRole(0);
            userTeam.setTeamId(teamId);
            userTeam.setTeamName(team.getName());
            userTeam.setUserId(team.getUserId());
            userTeam.setCreatorId(team.getUserId());
            userManager.addMyTeam(userTeam);
        } catch (DuplicateKeyException e) {
            LOGGER.debug("重复插入UserTeam表", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("您已创建过该比赛的团队,去看看别的比赛吧");
        } catch (RuntimeException e) {
            LOGGER.error("创建团队完成后加入userTeam表异常:", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("创建团队失败");
        }
        return result;
    }

    /**
     * 根据团队id获取团队详情
     *
     * @param id 团队id
     * @return 带竞赛实体的结果集
     */
    @Override
    public Result<Team> getTeamDescById(Integer id) {
        Result<Team> result = new Result<>();
        Team team = teamManager
                .getTeamDescById(id);
        if (team == null) {
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("出现异常，请返回重试");
            return result;
        }
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setBean(team);
        return result;
    }

    /**
     * 根据竞赛id获取团队列表.
     *
     * @param page          页码
     * @param rows          条数
     * @param competitionId 竞赛id
     * @return 结果集
     */
    @Override
    public Result<List<Team>> getTeamsByCompetitionId(Integer page, Integer rows, Integer competitionId) {
        Result<List<Team>> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("根据竞赛id获取团队列表成功");
        result.setBean(teamManager.getTeamsByCompetitionId(page, rows, competitionId));
        return result;
    }

    /**
     * 根据团队id和申请人id判断是否已申请过加入团队.
     *
     * @param teamId 团队id
     * @param userId 申请人id
     * @return
     */
    @Override
    public Result<Integer> getApplyStatus(Integer teamId, Integer userId) {
        Result<Integer> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("获取是否已申请加入比赛成功");
        result.setBean(teamManager.getApplyStatus(teamId, userId));
        return result;
    }

    /**
     * 根据id获取申请.
     *
     * @param id 申请的id
     * @return
     */
    @Override
    public Result<Apply> getApplyById(Integer id) {
        Result<Apply> result = new Result<>();
        Apply apply = teamManager.getApplyById(id);
        if (apply == null) {
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("申请不存在");
            return result;
        }
        result.setBean(apply);
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("根据id获取加入申请成功");
        return result;
    }

    /**
     * 根据申请id更改状态.
     *
     * @param applyId 申请id
     * @param status  要更改的状态
     * @return
     */
    @Override
    public Result<String> updateApplyStatus(Integer applyId, Integer status) {
        Result<String> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("处理请求成功");
        Integer updateStatus = teamManager.updateApplyStatus(applyId, status);
        if (updateStatus.equals(ResultTypeEnum.SUCCESS.getValue())) {
            if (status.equals(ApplyStatusEnum.AGREE.getStatus())) {
                Apply apply;
                try {
                    apply = teamManager.getApplyById(applyId);
                } catch (RuntimeException e) {
                    LOGGER.error("通过申请人id获取申请异常", e);
                    result.setCode(ResultTypeEnum.FAILED.getValue());
                    result.setBean("更新状态失败");
                    return result;
                }
                Integer userId = apply.getApplyUserId();
                User userNameAndPic;
                try {
                    userNameAndPic = userManager.getUserNameAndPicById(userId);
                } catch (RuntimeException e) {
                    LOGGER.error("通过用户id获取申用户异常", e);
                    result.setCode(ResultTypeEnum.FAILED.getValue());
                    result.setBean("更新状态失败");
                    return result;
                }
                // 添加到team_member表
                TeamMember teamMember = new TeamMember();
                String teamMemberName = userNameAndPic.getNickName();
                String teamMemberPic = userNameAndPic.getPic();
                String teamMemberExpert = apply.getAbility();
                teamMember.setTeamId(apply.getTeamId());
                teamMember.setUserId(userId);
                teamMember.setNickName(teamMemberName);
                teamMember.setUsername(userNameAndPic.getUsername());
                teamMember.setUserPic(teamMemberPic);
                teamMember.setExpert(teamMemberExpert);
                try {
                    teamManager.addTeamMember(teamMember);
                } catch (DuplicateKeyException e) {
                    LOGGER.debug("重复添加团队成员异常", e);
                } catch (RuntimeException e) {
                    LOGGER.error("添加团队成员异常", e);
                    result.setCode(ResultTypeEnum.FAILED.getValue());
                    result.setBean("添加团队成员失败");
                    return result;
                }
                // 添加到user_team表
                UserTeam userTeam = new UserTeam();
                String teamName = apply.getTeamName();
                String teamCompetitionName = apply.getCompetitionName();
                userTeam.setCompetitionName(teamCompetitionName);
                userTeam.setTeamName(teamName);
                userTeam.setRole(TeamRoleEnum.MEMBER.getValue());
                userTeam.setUserId(userId);
                userTeam.setTeamId(apply.getTeamId());
                userTeam.setCreatorId(apply.getTeamCreatorId());
                try {
                    userManager.addMyTeam(userTeam);
                } catch (DuplicateKeyException e) {
                    LOGGER.debug("重复添加我的团队异常", e);
                } catch (RuntimeException e) {
                    LOGGER.error("添加我的团队异常", e);
                    result.setCode(ResultTypeEnum.FAILED.getValue());
                    result.setBean("添加我的团队失败");
                    return result;
                }
                Integer updateResult = teamManager.updateTeamMemeberNum(apply.getTeamId());
                if (!updateResult.equals(ResultTypeEnum.SUCCESS.getValue())) {
                    result.setCode(ResultTypeEnum.FAILED.getValue());
                    result.setBean("团队已满");
                    return result;
                }
            }
            result.setBean("更新状态成功");
        } else {
            result.setBean("更新状态失败");
        }
        return result;
    }

    /**
     * 获取申请人同比赛其他团队的申请状态.
     *
     * @param applyUserId     申请人id
     * @param competitionName 比赛名称
     * @return 申请状态
     */
    @Override
    public Result<Integer> getOtherApplyStatus(Integer applyUserId, String competitionName) {
        Result<Integer> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setBean(ApplyStatusEnum.NOT_CHECK.getStatus());
        Set<Integer> statusList = teamManager.getOtherApplyStatus(applyUserId, competitionName);
        if (statusList.contains(ApplyStatusEnum.AGREE.getStatus())) {
            result.setBean(ApplyStatusEnum.AGREE.getStatus());
        }
        return result;
    }

    /**
     * 根据用户id获取我的申请列表.
     *
     * @param page   页码
     * @param rows   条数
     * @param userId 用户id
     * @return
     */
    @Override
    public Result<List<Apply>> getMyAppliesByUserId(Integer page, Integer rows, Integer userId) {
        Result<List<Apply>> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setBean(teamManager.getMyAppliesByUserId(page, rows, userId));
        result.setMessage("获取我的申请列表成功");
        return result;
    }

    @Override
    public Result<List<TeamMember>> getTeamMembers(Integer teamId) {
        Result<List<TeamMember>> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setBean(teamManager.getTeamMembers(teamId));
        result.setMessage("获取团队成员成功");
        return result;
    }
}
